package br.sqandal.sql.builders;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import br.sqandal.sql.elements.Column;
import br.sqandal.sql.elements.Table;
import br.sqandal.sql.joins.Join;


public class Select implements Query{

	private List<Table> tables;
	private List<Join> joins;
	private List<Column> outputColumns;
	
	// Constructors
	
	public Select(Table table){
		tables = new ArrayList<Table>();
		outputColumns = new ArrayList<Column>();
		joins = new ArrayList<Join>();
		
		tables.add(table);
	}
	
	// Methods
	
	public void addTable(Table table){
		for (Table tItem : tables) {
			if(tItem.equals(table)){
				return;
			}
		}
		for (Join jItem : joins){
			if (jItem.getTableJoined().equals(table)) {
				return;
			}
		}
		tables.add(table);
	}
	
	public void addOutputColumn(Column column){
		for (Column cItem : outputColumns) {
			if(cItem.equals(column)){
				return;
			}
		}
		outputColumns.add(column);
		addTable(column.getTable());
	}
	
	public void addJoin(Join join){
		for (Join jItem : joins) {
			if(jItem.equals(join)){
				return;
			}
		}
		for(Table tItem : tables){
			if(join.getTableJoined().equals(tItem)){
				tables.remove(tItem);
				break;
			}
		}
		joins.add(join);
	}
	
	/**
	 * Creates the SQL Query plain text as a String
	 */
	@Override
	public String toString() {
		
		StringBuffer sql = new StringBuffer();
		
		// SELECT
		
		sql.append("SELECT");
		
		// OUTPUT COLUMNS
		
		if(outputColumns.isEmpty()){
			sql.append("\n#t*");
		}else{
			
			Iterator<Column> it = outputColumns.iterator(); 
			
			int sizeColumnsList = outputColumns.size();
			int countColumns = 0;
			
			while(it.hasNext()){
				Column col = it.next();
				
				sql.append("\n#t"+col.getDeclarationName());
				
				if(++countColumns < sizeColumnsList){
					sql.append(",");
				}
			}
		}
		
		// FROM
		
		sql.append("\nFROM");
		
		// TABLES

		Iterator<Table> it = tables.iterator();
		
		int sizeTablesList = tables.size();
		int countTables = 0;
		
		while(it.hasNext()){
			Table t = it.next();
			
			sql.append("\n#t"+t.getDeclarationName());
			
			if(++countTables < sizeTablesList){
				sql.append(",");
			}
		}
		
		// JOINS
		
		for (Join j : joins) {
			sql.append("\n#t#t"+j.getDeclarationName());
		}
		
		return sql.toString().replaceAll("#t", "    ");
	}
	
}
